home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / cond < prev    next >
Encoding:
Text File  |  1988-04-08  |  5.4 KB  |  334 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *        cond.c
  10.  */
  11.  
  12. #include    "tex.h"
  13. #include    "cmds.h"
  14. #include    "heap.h"
  15. #include    "box.h"
  16. #include    "eq.h"
  17. #include    "eqstack.h"
  18. #include    "hash.h"
  19. #include    "token.h"
  20. #include    "tokenlists.h"
  21. #include    "scan.h"
  22. #include    "tokenstack.h"
  23. #include    "evalstack.h"
  24. #include    "file.h"
  25. #include    "print.h"
  26. #include    "error.h"
  27. #include    "cond.h"
  28.  
  29. ptr        cond_ptr;
  30. int        cur_if;
  31. int        if_limit;
  32. val        if_line;
  33.  
  34. val        skip_line;
  35.  
  36. get_x_token_or_active_char()
  37. {
  38.     get_x_token();
  39.     if (cur_cmd == RELAX && cur_chr == NO_EXPAND_FLAG) {
  40.         cur_cmd = ACTIVE_CHAR;
  41.         cur_chr = cur_tok - CS_TOKEN_FLAG - ACTIVE_BASE;
  42.     }
  43. }
  44.  
  45. push_cond()
  46. {
  47.     ptr        p;
  48.  
  49.     p = get_node(IF_NODE_SIZE);
  50.     link(p) = cond_ptr;
  51.     type(p) = if_limit;
  52.     subtype(p) = cur_if;
  53.     if_line_field(p) = if_line;
  54.     cond_ptr = p;
  55.     cur_if = cur_chr;
  56.     if_limit = IF_CODE;
  57.     if_line = line;
  58. }
  59.  
  60. pop_cond()
  61. {
  62.     ptr        p;
  63.  
  64.     p = cond_ptr;
  65.     if_line = if_line_field(p);
  66.     cur_if = subtype(p);
  67.     if_limit = type(p);
  68.     cond_ptr = link(p);
  69.     free_node(p, IF_NODE_SIZE);
  70. }
  71.  
  72. pass_text ()
  73. {
  74.     int        l;
  75.     int        save_scanner_status;
  76.  
  77.     l = 0;
  78.     save_scanner_status = scanner_status;
  79.     scanner_status = SKIPPING;
  80.     skip_line = line;
  81.     loop {
  82.         get_next();
  83.         if (cur_cmd == FI_OR_ELSE) {
  84.             if (l == 0)
  85.                 break;
  86.             if (cur_chr == FI_CODE)
  87.                 decr(l);
  88.         } else if (cur_cmd == IF_TEST)
  89.             incr(l);
  90.     }
  91.     scanner_status = save_scanner_status;
  92. }
  93.                     
  94. change_if_limit (l, p)
  95.     int        l;
  96.     ptr        p;
  97. {
  98.     ptr        q;
  99.  
  100.     if (p == cond_ptr)
  101.         if_limit = l;
  102.     else {
  103.         q = cond_ptr; 
  104.         loop {
  105.             if (q == NULL)
  106.                 confusion("if");
  107.             if (link(q) == p) {
  108.                 type(q) = l;
  109.                 return;
  110.             }
  111.             q = link(q);
  112.         }
  113.     }
  114. }
  115.  
  116. conditional ()
  117. {
  118.     bool    b;
  119.     val        m;
  120.     val        n;
  121.     ptr        p;
  122.     ptr        q;
  123.     ptr        r;
  124.     int        this_if;
  125.     ptr        save_cond_ptr;
  126.     int        save_scanner_status;
  127.  
  128.     push_cond();
  129.     save_cond_ptr = cond_ptr;
  130.     this_if = cur_chr;
  131.     switch (this_if)
  132.     {
  133.     case IF_CHAR_CODE:
  134.     case IF_CAT_CODE:
  135.         get_x_token_or_active_char();
  136.         if (cur_cmd > ACTIVE_CHAR || cur_chr > 127) {
  137.             m = RELAX;
  138.             n = 256;
  139.         } else {
  140.             m = cur_cmd;
  141.             n = cur_chr;
  142.         }
  143.         get_x_token_or_active_char();
  144.         if (cur_cmd > ACTIVE_CHAR || cur_chr > 127) {
  145.             cur_cmd = RELAX;
  146.             cur_chr = 256;
  147.         }
  148.         if (this_if == IF_CHAR_CODE)
  149.             b = (n == cur_chr);
  150.         else b = (m == cur_cmd);
  151.         break;
  152.     
  153.     case IF_INT_CODE:
  154.     case IF_DIM_CODE:
  155.         if (this_if == IF_INT_CODE)
  156.             scan_int();
  157.         else scan_normal_dimen();
  158.         n = cur_val;
  159.         get_nbx_token(); 
  160.         if (cur_tok >= OTHER_TOKEN + '<' &&
  161.             cur_tok <= OTHER_TOKEN + '>')
  162.             r = cur_tok - OTHER_TOKEN;
  163.         else {
  164.             print_err("Missing = inserted for ");
  165.             print_cmd_chr(IF_TEST, this_if);
  166.             help_relation();
  167.             back_error();
  168.             r = '=';
  169.         }
  170.         if (this_if == IF_INT_CODE)
  171.             scan_int();
  172.         else scan_normal_dimen();
  173.         switch (r)
  174.         {
  175.         case '<':
  176.             b = (n < cur_val);
  177.             break;
  178.  
  179.         case '=':
  180.             b = (n == cur_val);
  181.             break;
  182.  
  183.         case '>':
  184.             b = (n > cur_val);
  185.             break;
  186.         }
  187.         break;
  188.     
  189.     case IF_ODD_CODE:
  190.         scan_int();
  191.         b = odd(cur_val);
  192.         break;
  193.     
  194.     case IF_VMODE_CODE:
  195.         b = (abs(mode) == VMODE);
  196.         break;
  197.  
  198.     case IF_HMODE_CODE:
  199.         b = (abs(mode) == HMODE);
  200.         break;
  201.  
  202.     case IF_MMODE_CODE:
  203.         b = (abs(mode) == MMODE);
  204.         break;
  205.     
  206.     case IF_INNER_CODE:
  207.         b = (mode < 0);
  208.         break;
  209.     
  210.     case IF_VOID_CODE:
  211.     case IF_HBOX_CODE:
  212.     case IF_VBOX_CODE:
  213.         scan_eight_bit_int();
  214.         p = box(cur_val);
  215.         if (this_if == IF_VOID_CODE)
  216.             b = (p == NULL);
  217.         else if (p == NULL)
  218.             b = FALSE;
  219.         else if (this_if == IF_HBOX_CODE)
  220.             b = (type(p) == HLIST_NODE);
  221.         else b = (type(p) == VLIST_NODE);
  222.         break;
  223.  
  224.     case IFX_CODE:
  225.         save_scanner_status = scanner_status;
  226.         scanner_status = NORMAL;
  227.         get_next();
  228.         n = cur_cs;
  229.         p = cur_cmd;
  230.         q = cur_chr;
  231.         get_next(); 
  232.         if (cur_cmd != p)
  233.             b = FALSE;
  234.         else if (cur_cmd < CALL)
  235.             b = (cur_chr == q);
  236.         else {
  237.             p = token_link(cur_chr);
  238.             q = token_link(equiv(n));
  239.             while (p != NULL && q != NULL) {
  240.                 if (token(p) != token(q))
  241.                     p = NULL;
  242.                 else {
  243.                     p = token_link(p);
  244.                     q = token_link(q);
  245.                 }
  246.             }
  247.             b = (p == NULL && q == NULL);
  248.         }
  249.         scanner_status = save_scanner_status;
  250.         break;
  251.  
  252.     case IF_EOF_CODE:
  253.         scan_four_bit_int();
  254.         b = (read_open[cur_val] == CLOSED);
  255.         break;
  256.     
  257.     case IF_TRUE_CODE:
  258.         b = TRUE;
  259.         break;
  260.  
  261.     case IF_FALSE_CODE:
  262.         b = FALSE;
  263.         break;
  264.  
  265.     case IF_CASE_CODE: 
  266.         scan_int();
  267.         n = cur_val;
  268.         if (tracing_commands > 1) {
  269.             begin_diagnostic();
  270.             print("{case ");
  271.             print_int(n);
  272.             print_char('}');
  273.             end_diagnostic(FALSE);
  274.         }
  275.         while (n != 0) {
  276.             pass_text();
  277.             if (cond_ptr == save_cond_ptr) {
  278.                 if (cur_chr == OR_CODE)
  279.                     decr(n);
  280.                 else goto common_end;
  281.             } else if (cur_chr == FI_CODE)
  282.                 pop_cond();
  283.         }
  284.         change_if_limit(OR_CODE, save_cond_ptr);
  285.         return;
  286.     
  287.     default:
  288.         break;
  289.     }
  290.  
  291.     if (tracing_commands > 1) {
  292.         begin_diagnostic();
  293.         print(b ? "{true}" : "{false}");
  294.         end_diagnostic(FALSE);
  295.     }
  296.  
  297.     if (b) {
  298.         change_if_limit(ELSE_CODE, save_cond_ptr);
  299.         return;
  300.     }
  301.  
  302.     loop {
  303.         pass_text(); 
  304.         if (cond_ptr == save_cond_ptr) {
  305.             if (cur_chr != OR_CODE)
  306.                 goto common_end;
  307.             print_err("Extra ");
  308.             print_esc("or");
  309.             help_or();
  310.             error();
  311.         } else if (cur_chr == FI_CODE)
  312.             pop_cond();
  313.     }
  314.  
  315. common_end:
  316.     if (cur_chr == FI_CODE)
  317.         pop_cond();
  318.     else if_limit = FI_CODE;
  319. }
  320.  
  321. /*
  322.  *    Help text
  323.  */
  324.  
  325. help_or ()
  326. {
  327.     help1("I'm ignoring this; it doesn't match any \\if.");
  328. }
  329.  
  330. help_relation ()
  331. {
  332.     help1("I was expecting to see `<', `=', or `>'. Didn't.");
  333. }
  334.